package com.hibernate.hrm.config;

import com.hibernate.hrm.config.login.CustomAuthenticationFailureHandler;
import com.hibernate.hrm.config.login.CustomAuthenticationSuccessHandler;
import com.hibernate.hrm.config.login.CustomLogoutHandler;
import com.hibernate.hrm.service.login.UserDetailsServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    private final UserDetailsServiceImpl userDetailsService;
    private final CustomLogoutHandler customLogoutHandler;
    private final CustomAuthenticationSuccessHandler authenticationSuccessHandler;
    private final CustomAuthenticationFailureHandler authenticationFailureHandler;
    public SecurityConfig(UserDetailsServiceImpl userDetailsService,
                          CustomLogoutHandler customLogoutHandler,
                          CustomAuthenticationSuccessHandler authenticationSuccessHandler,
                          CustomAuthenticationFailureHandler authenticationFailureHandler
    ) {
        this.userDetailsService = userDetailsService;
        this.customLogoutHandler = customLogoutHandler;
        this.authenticationSuccessHandler = authenticationSuccessHandler;
        this.authenticationFailureHandler = authenticationFailureHandler;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                // 禁用CSRF（根据需求配置）
                .csrf(AbstractHttpConfigurer::disable)

                // 授权配置 - 使用现代请求匹配方式
                .authorizeHttpRequests(auth -> auth
                        // 1. 放行所有静态资源和登录页
                        .requestMatchers(
                                "/",
                                "/login",
                                "/static/**",
                                "/css/**",
                                "/js/**",
                                "/images/**",
                                "/webjars/**",
                                "/favicon.ico",
                                "/error"
                        ).permitAll()

                        // 2. 通用认证路由（无需重复指定角色）
                        .requestMatchers("/employee", "/employee/**").authenticated()
                        .requestMatchers("/department", "/department/**").authenticated()
                        .requestMatchers("/department/set-head/**").authenticated()
                        .requestMatchers("/position", "/position/**").authenticated()
                        .requestMatchers("/contract", "/contract/**").authenticated()

                        // 3. 按角色保护路由（确保路径唯一性）
                        .requestMatchers("/employee/add", "/employee/add/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR")
                        .requestMatchers(HttpMethod.POST, "/department/toggle-status/**").hasAnyRole("ADMIN", "BOSS")
                        .requestMatchers("/department/export").hasAnyRole("ADMIN", "BOSS", "HR_MGR")
                        .requestMatchers("/department/set-head/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR")
                        .requestMatchers("/department/edit", "/department/edit/**").hasAnyRole("ADMIN", "BOSS")
                        .requestMatchers("/department/add", "/department/add-child/**").hasAnyRole("ADMIN", "BOSS")
                        .requestMatchers(HttpMethod.POST, "/department/delete/**").hasAnyRole("ADMIN", "BOSS")
                        .requestMatchers("/position/add", "/position/edit/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR")
                        .requestMatchers(HttpMethod.POST, "/position/toggle-status/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR")
                        .requestMatchers("/position/view/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR", "DEPT_MGR")
                        .requestMatchers(HttpMethod.POST, "/position/delete/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR")
                        .requestMatchers("/contract/list/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR", "DEPT_MGR", "STAFF", "LEGAL")
                        .requestMatchers(HttpMethod.POST, "/contract/terminate/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR", "DEPT_MGR", "LEGAL")
                        .requestMatchers("/contract/view/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR", "DEPT_MGR", "LEGAL")
                        .requestMatchers("/contract/export/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR", "DEPT_MGR", "LEGAL")
                        .requestMatchers(HttpMethod.GET, "/contract/edit/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR", "LEGAL")
                        .requestMatchers(HttpMethod.POST, "/contract/edit/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR", "LEGAL")
                        .requestMatchers(HttpMethod.POST, "/contract/upload-attachment/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR", "LEGAL")
                        .requestMatchers(HttpMethod.DELETE, "/contract/delete-attachment/**").hasAnyRole("ADMIN", "BOSS", "HR_MGR", "LEGAL")

                        // 4. 其他请求需认证
                        .anyRequest().authenticated()
                )

                // 表单登录配置
                .formLogin(form -> form
                        .loginPage("/login")
                        .loginProcessingUrl("/login")
                        .successHandler(authenticationSuccessHandler) // 使用自定义成功处理器
                        .failureHandler(authenticationFailureHandler) // 使用自定义失败处理器
                        .permitAll()
                )

                // 登出配置
                .logout(logout -> logout
                        .addLogoutHandler(customLogoutHandler)
                        .logoutUrl("/logout")
                        .logoutSuccessUrl("/login?logout")
                        .permitAll()
                )

                // Remember-Me配置
                .rememberMe(remember -> remember
                        .key("uniqueAndSecret")
                        .tokenValiditySeconds(86400)
                        .userDetailsService(userDetailsService)
                )

                // 用户详情服务
                .userDetailsService(userDetailsService);

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}